﻿///
/// Copyright, 
/// This application , code and content is free to copy and modify 
/// This code is for demo purposed only 
/// User at own risk. no legal obligations from my end.
/// The purpose of this code is to explore the SharePoint Audit facilities.
/// George Gergues , george.gergues@gmail.com
/// Thank you.
///

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Data;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Administration;


namespace TIS.SPAuditDemo
{
    public class SPCustomAuditEntryCollection:ICollection
    {
        #region ICollection Members
        internal List<SPCustomAuditEntry> lstAE = new List<SPCustomAuditEntry>();
        //private SPAuditReportCache ItemsCache = new SPAuditReportCache();
        private SPCustomUsersCache UsersCache = new SPCustomUsersCache();
        
        internal SPSite siteCollection;        
        
        //local cache for internal found items.
        
        public DataTable toDataTable()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Occured", typeof(DateTime));
            dt.Columns.Add("User", typeof(string));
            dt.Columns.Add("Item_Type", typeof(string));
            dt.Columns.Add("Location_Type", typeof(string));                        
            dt.Columns.Add("Doc_Location", typeof(string));
            dt.Columns.Add("Version", typeof(string));
            
            dt.Columns.Add("Event_Name", typeof(string));
            dt.Columns.Add("Event_Type", typeof(string));
            dt.Columns.Add("Event_Source", typeof(string));
            dt.Columns.Add("Event_Data", typeof(string));

            ///Add those after the Cached Items.
            //dt.Columns.Add("Site_Id", typeof(string));
            //dt.Columns.Add("Site_Title", typeof(string));
            //dt.Columns.Add("Site_Url", typeof(string));

            ///Add those after the Cached Items.
            dt.Columns.Add("Item_Id", typeof(string));
            //dt.Columns.Add("Item_Title", typeof(string));
            //dt.Columns.Add("Item_Url", typeof(string));

            ///Custom Audit Event fields normally null.
            //dt.Columns.Add("Machine_IP", typeof(string));
            //dt.Columns.Add("Machine_Name", typeof(string));
            //dt.Columns.Add("Source_Name", typeof(string));
            
            
            DataRow dr;
            try
            {
                
                foreach (SPCustomAuditEntry au in lstAE)
                {
                    dr=dt.Rows.Add();
                    dr["Occured"] = au.Occurred;
                    dr["User"] = au.UserId;                    
                    dr["Item_Type"] = au.ItemType;
                    dr["Location_Type"] = au.LocationType;
                    
                    //dr["Machine_IP"] = au.MachineIP;
                    //dr["Machine_Name"] = au.MachineName;                    
                    //dr["Source_Name"] = au.SourceName;
                    
                    dr["Event_Type"] = au.EventType;
                    dr["Event_Source"] = au.EventSource;                    
                    dr["Event_Data"] = au.EventData;
                    dr["Doc_Location"] = au.DocLocation;
                    dr["Version"] = au.Version;
                    dr["Event_Name"] = au.EventName;

                    //dr["Site_Id"] = au.SiteId;
                    //dr["Site_Title"] = au.SiteTitle;
                    //dr["Site_Url"] = au.SiteUrl;

                    dr["Item_Id"] = au.ItemId.ToString();
                    //dr["Item_Title"] = au.ItemTitle;
                    //dr["Item_Url"] = au.ItemUrl;
                    //Start cache query here to reduce DB queries.
                }
            }
            catch 
            {
                dt.Clear();
            }

            return dt;
        }

        public void CopyTo(Array array, int index)
        {
            throw new NotImplementedException();
        }

        public int Count
        {
            get { throw new NotImplementedException(); }
        }

        public bool IsSynchronized
        {
            get { throw new NotImplementedException(); }
        }

        public object SyncRoot
        {
            get { throw new NotImplementedException(); }
        }

        #endregion

        #region IEnumerable Members

        public IEnumerator GetEnumerator()
        {
            throw new NotImplementedException();
        }

        #endregion

        public  void Add(SPCustomAuditEntry CustomAuditEntry)
        {
            SPCustomAuditEntry spc = CustomAuditEntry;            
            //Update the Custom properties
            //Using local cache if possible.
            
            //UserId -> User Display Name and User Account.
            #region CacheUser
            if (UsersCache.findUser(spc._SPAuditItem.UserId) != null)
            {
                spc.UserId = (UsersCache.findUser(spc._SPAuditItem.UserId).Name) + " (" + (UsersCache.findUser(spc._SPAuditItem.UserId).LoginName) + ")";                
            }
            else
            {
                //If the userID is valid 
                //Add the user to cache to reduce DB Trips. 
                if(spc._SPAuditItem.UserId >0)
                {
                UsersCache.AddUser(spc._SPAuditItem.UserId , siteCollection.RootWeb.SiteUsers.GetByID(spc._SPAuditItem.UserId ));
                }
                spc._SPAuditItem.UserId.ToString();
            }

            #endregion

            #region SiteCache
            ///SiteTitle.
            ///SiteUrl.
            ///found the item in cache.
            spc.Version = ParseVersionNumber(spc._SPAuditItem.EventData);
            lstAE.Add(spc);
        }
            #endregion  

        public SPCustomAuditEntryCollection(SPSite AuditSite)
        {
            siteCollection = AuditSite;
        }   
        
        #region helpers
        protected string ParseVersionNumber(string versionString)
        {
            try
            {
                if (versionString.ToLower().Contains("version"))
                {

                    int startMajor = versionString.IndexOf("<Major>") + 7;
                    int endMajor = versionString.IndexOf("</Major>");
                    int lengthMajor = endMajor - startMajor;
                    int startMinor = versionString.IndexOf("<Minor>") + 7;
                    int endMinor = versionString.IndexOf("</Minor>");
                    int lengthMinor = endMinor - startMinor;

                    string majorNumber = versionString.Substring(startMajor, lengthMajor);
                    string minorNumber = versionString.Substring(startMinor, lengthMinor);

                    if (majorNumber == "0" && minorNumber == "-1")
                        return "N/A";

                    return majorNumber + "." + minorNumber;
                }
                else
                    return "N/A";
            }
            catch
            {
                return versionString;
            }
        }
        #endregion
    }
}